"""
Meme 相关业务逻辑服务 (services/meme_service.py)

封装 Meme 的创建、查询、点赞等操作。
"""
from models.meme import load_memes, create_new_meme, get_meme_by_id
from utils.image_utils import generate_meme # 图片生成工具
from config.config import APP_CONFIG # 应用配置
from models.db_models import Upload # 使用Upload替代Meme模型
from models import db_session
import os
import logging
from flask import request
from sqlalchemy import text

# 配置日志记录器
logger = logging.getLogger(__name__)

def get_all_memes():
    """获取所有 Meme。"""
    return load_memes()

def get_meme(meme_id):
    """根据 ID 获取单个 Meme。"""
    return get_meme_by_id(meme_id)

def create_meme(data):
    """
    创建新的 Meme。
    如果提供了文字，会调用 `generate_meme` 生成图片。

    Args:
        data (dict): 包含 Meme 信息的字典。

    Returns:
        tuple: (Meme 字典, None) 或 (None, 错误信息)
    """
    required_fields = ['title', 'templateUrl', 'creator']
    if not all(field in data and data[field] for field in required_fields):
        logger.warning("创建 Meme 失败：缺少必要字段")
        return None, "缺少必要字段 (title, templateUrl, creator)"
    
    top_text = data.get('topText', '').strip()
    bottom_text = data.get('bottomText', '').strip()
    
    generated_image_url = None
    if top_text or bottom_text:
        output_folder = APP_CONFIG['UPLOAD_FOLDER']
        os.makedirs(output_folder, exist_ok=True)
        try:
            generated_filename = generate_meme(
                data['templateUrl'], top_text, bottom_text, output_folder
            )
            if not generated_filename:
                logger.error("Meme 图片生成失败")
                return None, "Meme 图片生成失败"
            # 构建生成图片的访问 URL (需要与路由匹配)
            # 假设 generate_meme 返回的文件名可以直接用于 /uploads/ 路径
            generated_image_url = f"/api/uploads/{generated_filename}" 
        except Exception as e:
            logger.error(f"Meme 图片生成过程中出错: {str(e)}")
            return None, f"生成 Meme 图片时出错: {str(e)}"
            
    url = generated_image_url if generated_image_url else data['templateUrl']
    
    new_meme = create_new_meme(
        data['title'], data['creator'], url, top_text, bottom_text
    )
    
    return new_meme, None

def like_meme(meme_id):
    """
    为指定 ID 的 Meme 点赞。

    Args:
        meme_id: Meme 的 ID。

    Returns:
        tuple: (更新后的 Meme 字典, None) 或 (None, 错误信息)
    """
    try:
        session = db_session()
        upload = session.query(Upload).filter(Upload.id == meme_id).first()
        
        if not upload:
            logger.warning(f"点赞失败：未找到 Meme ID {meme_id}")
            session.close()
            return None, "Meme 未找到"
            
        # 直接使用Upload模型中的likes字段
        upload.likes = (upload.likes or 0) + 1
        session.commit()
        
        # 转换为Meme字典返回
        meme_dict = upload.to_dict()
        # 添加兼容性字段
        meme_dict['title'] = upload.name
        meme_dict['topText'] = upload.top_text
        meme_dict['bottomText'] = upload.bottom_text
        meme_dict['creator'] = upload.created_by
        
        session.close()
        return meme_dict, None
    except Exception as e:
        logger.error(f"给Meme点赞时出错: {e}")
        return None, f"点赞时出错: {e}"

def get_templates():
    """
    获取可用的 Meme 模板列表 (当前为硬编码)。
    
    Returns:
        list: Meme 模板列表。
    """
    # 示例模板数据
    templates = [
        {
            "id": "1",
            "name": "Drake Hotline Bling",
            "url": "https://i.imgflip.com/30b1gx.jpg"
        },
        {
            "id": "2",
            "name": "Two Buttons",
            "url": "https://i.imgflip.com/1g8my4.jpg"
        },
        {
            "id": "3",
            "name": "Distracted Boyfriend",
            "url": "https://i.imgflip.com/1ur9b0.jpg"
        },
        {
            "id": "4",
            "name": "Expanding Brain",
            "url": "https://i.imgflip.com/1jwhww.jpg"
        },
        {
            "id": "5",
            "name": "Change My Mind",
            "url": "https://i.imgflip.com/24y43o.jpg"
        }
    ]
    return templates

def get_latest_templates(page=1, limit=10):
    """
    获取最新的表情包模板列表，支持分页。
    
    Args:
        page (int): 当前页码，从1开始
        limit (int): 每页显示的条目数量
    
    Returns:
        dict: 包含分页和模板数据的结果
    """
    try:
        session = db_session()
        # 查询总数 - 只获取有名称的Upload记录（表情）
        total_count = session.query(Upload).filter(Upload.name != None).count()
        
        # 计算分页
        offset = (page - 1) * limit
        
        # 按创建时间倒序查询
        templates_db = session.query(Upload).filter(Upload.name != None).order_by(Upload.created_at.desc()).offset(offset).limit(limit).all()
        
        # 转换为字典列表
        templates = []
        for template in templates_db:
            template_dict = template.to_dict()
            # 格式化为前端需要的格式
            templates.append({
                "id": template_dict["id"],
                "name": template_dict["name"],
                "url": template_dict["url"],
                "description": template_dict.get("description", ""),
                "createdAt": template_dict.get("createdAt")
            })
        
        session.close()
        
        # 计算总页数
        total_pages = (total_count + limit - 1) // limit
        
        return {
            "templates": templates,
            "pagination": {
                "page": page,
                "limit": limit,
                "totalItems": total_count,
                "totalPages": total_pages
            }
        }
            
    except Exception as e:
        logger.error(f"获取最新表情包列表时出错: {str(e)}")
        return None 

def get_latest_memes(page=1, limit=10):
    """
    获取最新上传的表情包列表，支持分页。
    数据来源为uploads表和uploads目录。
    
    Args:
        page (int): 当前页码，从1开始
        limit (int): 每页显示的条目数量
    
    Returns:
        dict: 包含分页和表情包数据的结果
    """
    try:
        # 获取服务器基础URL
        base_url = request.host_url.rstrip('/')
        
        session = db_session()
        # 查询总数 - 获取上传的表情包记录
        total_count = session.query(Upload).count()
        
        # 计算分页
        offset = (page - 1) * limit
        
        # 按创建时间倒序查询
        memes_db = session.query(Upload).order_by(Upload.created_at.desc()).offset(offset).limit(limit).all()
        
        # 转换为字典列表
        memes = []
        for meme in memes_db:
            meme_dict = meme.to_dict()
            # 格式化为前端需要的格式，并确保URL是完整的绝对URL
            url = meme_dict["url"]
            if url:
                # 去除开头可能的 /api/
                if url.startswith('/api/'):
                    url = url[5:]  # 跳过 "/api/" 前缀
                # 确保URL是完整的绝对URL
                if not url.startswith(('http://', 'https://')):
                    url = f"{base_url}/api/{url}"
            
            memes.append({
                "id": meme_dict["id"],
                "title": meme_dict.get("name", ""),
                "url": url,
                "topText": meme_dict.get("topText", ""),
                "bottomText": meme_dict.get("bottomText", ""),
                "likes": meme_dict.get("likes", 0),
                "creator": meme_dict.get("createdBy", ""),
                "createdAt": meme_dict.get("createdAt"),
                "fileType": meme_dict.get("fileType", ""),
                "fileSize": meme_dict.get("fileSize", 0),
                "tags": meme_dict.get("tags", [])
            })
        
        session.close()
        
        # 计算总页数
        total_pages = (total_count + limit - 1) // limit if total_count > 0 else 0
        
        return {
            "memes": memes,
            "pagination": {
                "page": page,
                "limit": limit,
                "totalItems": total_count,
                "totalPages": total_pages
            }
        }
            
    except Exception as e:
        logger.error(f"获取最新上传的表情包列表时出错: {str(e)}")
        return {
            "memes": [],
            "pagination": {
                "page": page,
                "limit": limit,
                "totalItems": 0,
                "totalPages": 0
            },
            "error": str(e)
        } 

def search_memes_by_tag(tag_keyword, page=1, limit=10):
    """
    根据标签关键字搜索表情包。
    
    Args:
        tag_keyword (str): 标签关键字
        page (int): 当前页码，从1开始
        limit (int): 每页显示的条目数量
    
    Returns:
        dict: 包含分页和表情包数据的结果
    """
    try:
        # 获取服务器基础URL
        base_url = request.host_url.rstrip('/')
        
        session = db_session()
        
        # 由于 JSON_SEARCH 可能不可用，使用基本的 LIKE 语法
        # 将 tags 字段作为字符串进行搜索
        from sqlalchemy import or_, and_
        
        # 创建一个基本查询，筛选出存在 tags 的记录
        query = session.query(Upload).filter(Upload.tags != None)
        
        # 使用 JSON 字符串匹配的方式查找包含标签的记录
        # 转换标签关键字为小写，方便不区分大小写匹配
        tag_keyword_lower = tag_keyword.lower()
        
        # 手动过滤包含关键字的记录
        all_memes = query.all()
        filtered_memes = []
        
        for meme in all_memes:
            if meme.tags:
                # 尝试在标签数组中查找包含关键字的标签
                for tag in meme.tags:
                    if isinstance(tag, str) and tag_keyword_lower in tag.lower():
                        filtered_memes.append(meme)
                        break
        
        # 按创建时间排序
        filtered_memes.sort(key=lambda x: x.created_at, reverse=True)
        
        # 计算总数和分页
        total_count = len(filtered_memes)
        offset = (page - 1) * limit
        memes_db = filtered_memes[offset:offset + limit] if offset < total_count else []

        # 转换为字典列表
        memes = []
        for meme in memes_db:
            meme_dict = meme.to_dict()
            # 格式化为前端需要的格式，并确保URL是完整的绝对URL
            url = meme_dict["url"]
            if url:
                # 去除开头可能的 /api/
                if url.startswith('/api/'):
                    url = url[5:]  # 跳过 "/api/" 前缀
                # 确保URL是完整的绝对URL
                if not url.startswith(('http://', 'https://')):
                    url = f"{base_url}/api/{url}"
            
            memes.append({
                "id": meme_dict["id"],
                "title": meme_dict.get("name", ""),
                "url": url,
                "topText": meme_dict.get("topText", ""),
                "bottomText": meme_dict.get("bottomText", ""),
                "likes": meme_dict.get("likes", 0),
                "creator": meme_dict.get("createdBy", ""),
                "createdAt": meme_dict.get("createdAt"),
                "fileType": meme_dict.get("fileType", ""),
                "fileSize": meme_dict.get("fileSize", 0),
                "tags": meme_dict.get("tags", [])
            })
        
        session.close()
        
        # 计算总页数
        total_pages = (total_count + limit - 1) // limit if total_count > 0 else 0
        
        return {
            "memes": memes,
            "pagination": {
                "page": page,
                "limit": limit,
                "totalItems": total_count,
                "totalPages": total_pages
            }
        }
            
    except Exception as e:
        logger.error(f"根据标签搜索表情包时出错: {str(e)}")
        return {
            "memes": [],
            "pagination": {
                "page": page,
                "limit": limit,
                "totalItems": 0,
                "totalPages": 0
            },
            "error": str(e)
        } 